/**
 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
 */
package com.jeesite.modules.sd.service;

import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Extend;
import com.jeesite.common.mybatis.mapper.query.QueryType;
import com.jeesite.modules.sd.common.constants.FileCabinetRecordEnum;
import com.jeesite.modules.sd.common.constants.RecvConstant;
import com.jeesite.modules.sd.common.util.HttpUtil;
import com.jeesite.modules.sys.entity.EmpUser;
import com.jeesite.modules.sys.entity.Office;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.EmpUserService;
import com.jeesite.modules.sys.service.OfficeService;
import com.jeesite.modules.sys.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jeesite.common.entity.Page;
import com.jeesite.common.service.CrudService;
import com.jeesite.modules.sd.entity.FileCabinetRecord;
import com.jeesite.modules.sd.dao.FileCabinetRecordDao;

/**
 * 系统与文件柜交互记录表Service1
 *
 * @author linyh
 * @version 2020-07-29
 */
@Slf4j
@Service
@Transactional(readOnly = true)
public class FileCabinetRecordService extends CrudService<FileCabinetRecordDao, FileCabinetRecord> {

    @Autowired
    private UserService userService;

    @Autowired
    private EmpUserService empUserService;

    @Autowired
    private OfficeService officeService;

    @Autowired
    private DocDeliverRecordService docDeliverRecordService;

    /**
     * 获取单条数据
     *
     * @param fileCabinetRecord
     * @return
     */
    @Override
    public FileCabinetRecord get(FileCabinetRecord fileCabinetRecord) {
        return super.get(fileCabinetRecord);
    }

    /**
     * 查询分页数据
     *
     * @param fileCabinetRecord      查询条件
     * @param fileCabinetRecord.page 分页对象
     * @return
     */
    @Override
    public Page<FileCabinetRecord> findPage(FileCabinetRecord fileCabinetRecord) {
        return super.findPage(fileCabinetRecord);
    }

    /**
     * 保存数据（插入或更新）
     *
     * @param fileCabinetRecord
     */
    @Override
    @Transactional(readOnly = false)
    public void save(FileCabinetRecord fileCabinetRecord) {
        super.save(fileCabinetRecord);
    }

    /**
     * 更新状态
     *
     * @param fileCabinetRecord
     */
    @Override
    @Transactional(readOnly = false)
    public void updateStatus(FileCabinetRecord fileCabinetRecord) {
        super.updateStatus(fileCabinetRecord);
    }

    /**
     * 删除数据
     *
     * @param fileCabinetRecord
     */
    @Override
    @Transactional(readOnly = false)
    public void delete(FileCabinetRecord fileCabinetRecord) {
        super.delete(fileCabinetRecord);
    }

    /**
     * 向文件柜发送命令
     *
     * @param fileCabinetRecord 交互记录
     */
    public boolean sendCabinetCommand(FileCabinetRecord fileCabinetRecord) {
        // TODO URL定义在配置文件或者常量
        String url = "http://127.0.0.1:8080/sd/simulateThirdParty/openMailBox";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cabinetno", fileCabinetRecord.getCabinetno());
        jsonObject.put("responseStatus", fileCabinetRecord.getResponseStatus());
        jsonObject.put("processCode", fileCabinetRecord.getProcessCode());
        String s = HttpUtil.executeUrlOfJson(url, jsonObject);
        JSONObject object = JSONObject.parseObject(s);
        if (null != object && "true".equals(object.get("status").toString())) {
            log.info("发送命令成功");
            return true;
        } else {
            log.error("发送命令失败");
            return false;
        }

    }

    /**
     * 保存人脸结果
     *
     * @param fileCabinetRecord
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveResultOfFaceRecognition(FileCabinetRecord fileCabinetRecord) {

        long currentTimeMillis = System.currentTimeMillis();
        String status;

        // 人脸结果记录
        fileCabinetRecord.setRecordDate(new Date());
        fileCabinetRecord.setProcessCode(currentTimeMillis + "");
        fileCabinetRecord.setResponseType(FileCabinetRecordEnum.TYPE_USER_FACE_RESULT.getValue());

        // 人脸识别未通过,记录并拒绝
        if (FileCabinetRecordEnum.STATUS_FAILURE.getValue().
                equals(fileCabinetRecord.getResponseStatus())) {
            fileCabinetRecord.setRemark(FileCabinetRecordEnum.FACE_FAILURE_REMARK.getRemark());
            // 保存人脸识别记录(无文件柜号)
            save(fileCabinetRecord);
            status = fileCabinetRecord.getResponseStatus();
        } else {

            Map userAndOffice = getUserAndOffice(fileCabinetRecord.getPoliceno(),
                    fileCabinetRecord.getUserName());

            // 人脸识别结果非系统录入用户,记录并拒绝
            if (null == userAndOffice) {

                fileCabinetRecord.setRemark(FileCabinetRecordEnum.IDENTIFY_SUCCESS_REMARK.getRemark());
                // 保存人脸识别记录(无文件柜号)
                save(fileCabinetRecord);
                fileCabinetRecord.setRemark(FileCabinetRecordEnum.SYSTEM_FAILURE_REMARK.getRemark());
                // 改变响应状态
                status = FileCabinetRecordEnum.STATUS_FAILURE.getValue();
            } else {
                Office office = (Office) userAndOffice.get("office");
                User user1 = (User) userAndOffice.get("user");

                // 文件柜号
                String cabinetno = office.getExtend().getExtendS4();
                fileCabinetRecord.setCabinetno(cabinetno);
                fileCabinetRecord.setRemark(FileCabinetRecordEnum.IDENTIFY_SUCCESS_REMARK.getRemark());
                // 保存人脸识别记录
                save(fileCabinetRecord);

                //TODO 如果人脸识别通过、用户状态正常且系统开启人脸开门，则开门
                String config = Global.getConfig("doc.fileCabinet.IdentificationType", "1");
                if (RecvConstant.STATUS_NORMAL.equals(user1.getStatus()) && "1".equals(config)) {
                    status = FileCabinetRecordEnum.STATUS_SUCCESS.getValue();

                } else {
                    status = FileCabinetRecordEnum.STATUS_FAILURE.getValue();
                    fileCabinetRecord.setRemark(FileCabinetRecordEnum.USER_FAILURE_REMARK.getRemark());
                }
            }
        }

        fileCabinetRecord.setResponseStatus(status);
        fileCabinetRecord.setResponseType(FileCabinetRecordEnum.TYPE_CABINET_COMMAND.getValue());
        // 发送命令
        boolean sendCabinetCommand = sendCabinetCommand(fileCabinetRecord);
        if (!sendCabinetCommand) {
            throw new RuntimeException("发送命令失败");
        }
        // 保存发送命令记录
        fileCabinetRecord.setId(null);
        fileCabinetRecord.setRecordDate(new Date());
        save(fileCabinetRecord);
        return true;
    }

    /**
     * 保存开/关门结果
     *
     * @param fileCabinetRecord
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOpenCloseResult(FileCabinetRecord fileCabinetRecord) {
        String responseStatus = fileCabinetRecord.getResponseStatus();
        fileCabinetRecord.setResponseStatus(null);

        // 查询该流程记录
        List<FileCabinetRecord> fileCabinetRecordServiceList = findList(fileCabinetRecord);
        FileCabinetRecord record = fileCabinetRecordServiceList.get(0);
        String respType = null;

        // 流程记录不为空
        if (Objects.nonNull(record)) {

            if (FileCabinetRecordEnum.STATUS_FAILURE.getValue().equals(record.getResponseStatus())) {
                log.error("流程编号为：{}的流程已经终止，不能继续操作", fileCabinetRecord.getProcessCode());
                throw new RuntimeException("操作失败，流程已经终止");
            }

            // 判断响应类型
            if (FileCabinetRecordEnum.TYPE_CABINET_COMMAND.getValue()
                    .equals(record.getResponseType())) {
                respType = FileCabinetRecordEnum.TYPE_CABINET_OPEN_RESULT.getValue();

                Map userAndOffice = getUserAndOffice(record.getPoliceno(), record.getUserName());
                if (null != userAndOffice) {
                    Office office = (Office) userAndOffice.get("office");
                    User user1 = (User) userAndOffice.get("user");
                    // 领文
                    docDeliverRecordService.takeDoc(office.getOfficeCode(),user1.getUserName(),
                            user1.getExtend().getExtendS1(),record.getUserFace(), user1.getUserCode());
                } else {
                    throw new RuntimeException("操作失败，没有该用户信息");
                }
            } else if (FileCabinetRecordEnum.TYPE_CABINET_OPEN_RESULT.getValue()
                    .equals(record.getResponseType())) {
                respType = FileCabinetRecordEnum.TYPE_CABINET_CLOSE_RESULT.getValue();
            }

            // 更新已操作
            FileCabinetRecord fileCabinetRecord1 = new FileCabinetRecord();
            fileCabinetRecord1.setId(record.getId());
            fileCabinetRecord1.setOperation(FileCabinetRecordEnum.HAS_BEEN_OPERATING.getValue());
            update(fileCabinetRecord1);

            // 判断状态，修改备注
            if (FileCabinetRecordEnum.STATUS_SUCCESS.getValue().equals(responseStatus)) {
                record.setRemark(FileCabinetRecordEnum.IDENTIFY_SUCCESS_REMARK.getRemark());
            } else {
                record.setRemark(FileCabinetRecordEnum.STATUS_FAILURE.getRemark());
            }

            record.setResponseType(respType);
            record.setResponseStatus(responseStatus);
            record.setId(null);
            record.setRecordDate(new Date());
            save(record);
            return true;
        }
        return false;
    }

    /**
     * 根据警号与姓名获取user、office
     *
     * @param policeno
     * @param userName
     * @return
     */
    public Map getUserAndOffice(String policeno, String userName) {
        HashMap<Object, Object> map = new HashMap<>();
        // 查询用户信息
        User user = new User();
        Extend extend = new Extend();
        extend.setExtendS1(policeno);
        user.setExtend(extend);
        user.getSqlMap().getWhere().and("user_name",
                QueryType.EQ, userName);
        List<User> userServiceList = userService.findList(user);

        if (CollectionUtils.isNotEmpty(userServiceList)) {
            User user1 = userServiceList.get(0);
            // 查询单位信息
            EmpUser empUser = new EmpUser();
            empUser.setUserCode(user1.getUserCode());
            List<EmpUser> empUserServiceList = empUserService.findList(empUser);
            EmpUser empUser1 = empUserServiceList.get(0);
            Office office = officeService.get(empUser1.getEmployee().getOffice());
            String extendS4 = office.getExtend().getExtendS4();
            // 0 则是送文单位
            if (!"0".equals(extendS4)){
                map.put("office", office);
                map.put("user", user1);
                return map;
            }
            throw new RuntimeException("该用户不属于领文单位");
        }
        return null;
    }
}